package com.ndhutu.ee.util.pay.zunpay;

import com.alibaba.fastjson.JSONObject;
import com.ndhutu.ee.util.MD5Util;
import com.ndhutu.ee.util.StringUtil;
import com.ndhutu.ee.util.http.OKHttpUtil;
import com.ndhutu.ee.util.pay.Notify;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class ZunPayUtil {
    private static Logger log = LoggerFactory.getLogger(ZunPayUtil.class);

    /**
     * 下单
     * @param config
     * @param orderNumber
     * @param amount
     * @param body
     * @return
     * @throws Exception
     */
    public static String order(ZunPayConfig config, String orderNumber, Integer amount, String body) throws Exception{
        Map<String, String> param = new HashMap<>();

        param.put("service", "1001");
        param.put("mch_id", config.getMchId());
        param.put("second_mch_id", config.getSecondMchId());
        param.put("pay_type", config.getPayType());
        param.put("body", body);
        param.put("mch_order_id", orderNumber);
        param.put("order_money", amount/100.0 + "");
        param.put("notify_url", config.getNotifyUrl());
        param.put("callback_url", config.getCallbackUrl());
        param.put("create_ip", "127.0.0.1");
        param.put("nonce_str", StringUtil.getRandomNumberStr());
        param.put("key", config.getKey());    //签名使用，签名后需要删除

        String sign = MD5Util.encode32(OKHttpUtil.sortParam(param, false));
        param.put("sign", sign);
        param.remove("key");

        String url = "https://pay.zunpay.net/pay/gateway";

        String result = OKHttpUtil.post(url, param);
        log.info("尊付下单返回结果："+result);
        Map<String, Object> map = JSONObject.parseObject(result, Map.class);
        if("200".equals(map.get("status"))){
            return map.get("pay_url")+"";
        }else{
            log.error("尊付下单失败，原因："+map.get("message"));
            throw new Exception("下单失败，"+map.get("message"));
        }
    }

    /**
     * 下单(新接口)
     * @param config
     * @param orderNumber
     * @param amount
     * @param body
     * @return
     * @throws Exception
     */
    public static String order2(ZunPayConfig config, String orderNumber, Integer amount, String body) throws Exception{
        Map<String, String> param = new HashMap<>();

        param.put("service", "4001");
        param.put("mch_id", config.getSecondMchId());
        param.put("agent_id", "10011");
        param.put("pay_type", config.getPayType());
        param.put("pay_way", "js");
        param.put("body", body);
        param.put("mch_order_id", orderNumber);
        param.put("order_money", amount/100.0 + "");
        param.put("callback_url", config.getCallbackUrl());
        param.put("notify_url", config.getNotifyUrl());
        param.put("create_ip", "127.0.0.1");
        param.put("nonce_str", StringUtil.getRandomNumberStr());
        param.put("key", config.getKey());    //签名使用，签名后需要删除

        String sign = MD5Util.encode32(OKHttpUtil.sortParam(param, false));
        param.put("sign", sign);
        param.remove("key");

        String url = "https://pay.mergepay.net/pay/gateway";

        String result = OKHttpUtil.post(url, param);
        log.info("尊付下单返回结果："+result);
        Map<String, Object> map = JSONObject.parseObject(result, Map.class);
        if("200".equals(map.get("status"))){
            return map.get("pay_url")+"";
        }else{
            log.error("尊付下单失败，原因："+map.get("message"));
            throw new Exception("下单失败，"+map.get("message"));
        }
    }

    /**
     * 获取回调请求参数
     * @param request
     * @return
     * @throws Exception
     */
    public static Map<String, String> getNotifyRequestParams(HttpServletRequest request) throws Exception{
        Map<String,String> params = new HashMap<String, String>();

        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        log.info("尊付支付回调参数："+ JSONObject.toJSONString(params));

        return params;
    }

    /**
     * 校验回调请求
     * @param params    回调请求参数
     * @param config
     * @param notify
     * @return
     * @throws Exception
     */
    public static String verifyNotifyRequest(Map<String, String> params, ZunPayConfig config, Notify notify) throws Exception{
        //签名验证
        boolean flag = false;
        params.put("key", config.getKey());
        String orgSign = params.get("sign");
        params.remove("sign");
        String sign = MD5Util.encode32(OKHttpUtil.sortParam(params, false));
        if(sign.equals(orgSign)){
            flag = true;
        }

        if(flag){
            if("2".equals(params.get("pay_result"))) {
                String orderNumber = params.get("mch_order_id");
                Integer amount = (int) (Double.parseDouble(params.get("order_money")) * 100);

                //统一回调
                notify.handleNotify(orderNumber, amount);
                log.info("订单" + orderNumber + "尊付回调成功");
            }
            return "success";
        }else{
            return "failure";
        }
    }

    public static void main(String[] args) throws Exception{
        ZunPayConfig config = new ZunPayConfig() {
            @Override
            public String getMchId() {
                return "100021724865723";
            }

            @Override
            public String getSecondMchId() {
                return "100072802360172";
            }

            @Override
            public String getPayType() {
                return "101";
            }

            @Override
            public String getNotifyUrl() {
                return "http://test.mm.api.ppmkf.com/mm-api/wallet/zunPayNotify";
            }

            @Override
            public String getCallbackUrl() {
                return "http://share.mm.ppmkf.com/pay/success_pay.html";
            }

            @Override
            public String getKey() {
                return "45c3b845e548365a579c07ec504f1476";
            }
        };

        String result = order(config, "12345678", 10, "测试商品");
        System.out.println(result);

//        String result = "{\"third_order_id\":\"2020102622001417425741191957\",\"nonce_str\":\"323849\",\"mch_order_id\":\"1603723044284613\",\"sign\":\"d8734d72c035274a225408a228415c3a\",\"order_money\":\"0.01\",\"pay_type\":\"101\",\"time_end\":\"1603723055\",\"mch_id\":\"100021724865723\",\"pay_money\":\"0.01\",\"order_id\":\"2020102622372435277\",\"pay_result\":\"2\"}";
//        Map<String, String> params = JSONObject.parseObject(result, Map.class);
//
//        verifyNotifyRequest(params, config, null);

//        String str = "body=联调测试&create_ip=127.0.0.1&key=06b55f2147d4f325fed6770d5ea15658&mch_id=201914608345415&mch_order_id=987654321&nonce_str=123456¬ify_url=http://127.0.0.1/notify.php&order_money=1&pay_type=101&service=1001";
//        System.out.println(MD5Util.encode32(str));
    }
}
